home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 August: Tool Chest / Apple_Developer_Group_August_1996_Tool_Chest.iso / Sample Code / Snippets / Files / PutAwayVolumes / PutAwayOneVolume.c next >
Encoding:
Text File  |  1996-05-24  |  6.3 KB  |  273 lines  |  [TEXT/CWIE]

  1.     //
  2.     //    You may incorporate this sample code into your applications without
  3.     //    restriction, though the sample code has been provided "AS IS" and the
  4.     //    responsibility for its operation is 100% yours.  However, what you are
  5.     //    not permitted to do is to redistribute the source as "DSC Sample Code"
  6.     //    after having made changes. If you're going to re-distribute the source,
  7.     //    we require that you make it clear in the source that the code was
  8.     //    descended from Apple Sample Code, but that you've made changes.
  9.     //
  10.     //    Complaints and kudos to:
  11.     //
  12.     //        Pete Gontier
  13.     //        Apple Macintosh Developer Technical Support
  14.     //        <gurgle@apple.com>
  15.     //
  16.     //    Change history:
  17.     //
  18.     //        PG    03/21/96    Created
  19.     //
  20.  
  21. #define OLDROUTINELOCATIONS        0
  22. #define OLDROUTINENAMES            0
  23. #define SystemSevenOrLater        1
  24.  
  25. #ifndef __DIALOGS__
  26. #    include <Dialogs.h>
  27. #endif
  28.  
  29. #ifndef __AEREGISTRY__
  30. #    include <AERegistry.h>
  31. #endif
  32.  
  33. #ifndef __APPLEEVENTS__
  34. #    include <AppleEvents.h>
  35. #endif
  36.  
  37. #ifndef __MOREFILESEXTRAS__
  38. #    include "MoreFilesExtras.h"
  39. #endif
  40.  
  41. #ifndef __ALIASES__
  42. #    include <Aliases.h>
  43. #endif
  44.  
  45. #ifndef __FOLDERS__
  46. #    include <Folders.h>
  47. #endif
  48.  
  49. #include "PutAwayOneVolume.h"
  50.  
  51. #if GENERATINGCFM
  52.  
  53. #ifndef __TRAPS__
  54. #    include <Traps.h>
  55. #endif
  56.  
  57. pascal OSErr ReleaseFolder (short vRefNum, OSType folderType)
  58. {
  59.     const unsigned long selector = 0xB;
  60.  
  61.     enum
  62.     {
  63.         uppReleaseFolderInfo = kD0DispatchedPascalStackBased
  64.             | RESULT_SIZE (SIZE_CODE (sizeof(OSErr)))
  65.             | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE (SIZE_CODE (sizeof (selector)))
  66.             | DISPATCHED_STACK_ROUTINE_PARAMETER (1,SIZE_CODE (sizeof (vRefNum)))
  67.             | DISPATCHED_STACK_ROUTINE_PARAMETER (2,SIZE_CODE (sizeof (folderType)))
  68.     };
  69.  
  70.     return CallUniversalProc (GetToolTrapAddress (_AliasDispatch), uppReleaseFolderInfo, selector, vRefNum, folderType);
  71. }
  72.  
  73. #endif
  74.  
  75. static pascal OSErr BuildAppleEvent (short vRefNum, AppleEvent *event)
  76. {
  77.     OSErr err = noErr;
  78.  
  79.     FSSpecPtr fssP = (FSSpecPtr) NewPtr (sizeof (*fssP));
  80.     if (!(err = MemError ( )))
  81.     {
  82.         if (!(err = FSMakeFSSpec (vRefNum, fsRtDirID, nil, fssP)))
  83.         {
  84.             AliasHandle aliasH;
  85.         
  86.             if (!(err = NewAlias (nil, fssP, &aliasH)))
  87.             {
  88.                 HLockHi ((Handle) aliasH);
  89.                 if (!(err = MemError ( )))
  90.                 {
  91.                     Size size = GetHandleSize ((Handle) aliasH);
  92.                     if (!(err = MemError ( )))
  93.                     {
  94.                         if (!(err = AEPutParamPtr (event,keyDirectObject,typeAlias,*aliasH,size)))
  95.                         {
  96.                             AEDescList aeDescList;
  97.                         
  98.                             if (!(err = AECreateList (nil,0,false,&aeDescList)))
  99.                             {
  100.                                 if (!(err = AEPutPtr (&aeDescList,1,typeAlias,*aliasH,size)))
  101.                                     err = AEPutParamDesc (event,keySelection,&aeDescList);
  102.                         
  103.                                 AEDisposeDesc (&aeDescList);
  104.                             }
  105.                         }
  106.                     }
  107.                 }
  108.                 DisposeHandle ((Handle) aliasH);
  109.                 if (!err) err = MemError ( );
  110.             }
  111.         }
  112.         DisposePtr ((Ptr) fssP);
  113.         if (!err) err = MemError ( );
  114.     }
  115.  
  116.     return err;
  117. }
  118.  
  119. static pascal OSErr PutAwayOneVolumeByAppleEvent (short vRefNum, OSType finderLikeProcess)
  120. {
  121.     OSErr err = noErr;
  122.  
  123.     AEAddressDesc address;
  124.  
  125.     if (!(err = AECreateDesc (typeApplSignature, &finderLikeProcess, sizeof (finderLikeProcess), &address)))
  126.     {
  127.         AppleEvent event;
  128.  
  129.         if (!(err = AECreateAppleEvent (kAEFinderEvents,kAEPutAwaySelection,&address,kAutoGenerateReturnID,kAnyTransactionID,&event)))
  130.         {
  131.             if (!(err = BuildAppleEvent (vRefNum, &event)))
  132.             {
  133.                 AppleEvent reply;
  134.                 err = AESend (&event,&reply,kAENoReply,kAENormalPriority,kAEDefaultTimeout,nil,nil);
  135.             }
  136.  
  137.             AEDisposeDesc (&event);
  138.         }
  139.  
  140.         AEDisposeDesc (&address);
  141.     }
  142.  
  143.     return err;
  144. }
  145.  
  146. static pascal Boolean ConfirmEmptyTrash (short vRefNum, Boolean *confirmed)
  147. {
  148.     OSErr        err        = noErr;
  149.     DialogRef    dlgRef    = nil;
  150.     
  151.     *confirmed = false;
  152.  
  153.     dlgRef = GetNewDialog (128,nil,(DialogRef)-1);
  154.     if (dlgRef && !SetDialogDefaultItem (dlgRef,ok))
  155.     {
  156.         FSSpecPtr fssP = (FSSpecPtr) NewPtr (sizeof (FSSpec));
  157.  
  158.         if (!(err = MemError ( )))
  159.         {
  160.             if (!FSMakeFSSpec (vRefNum,fsRtDirID,nil,fssP))
  161.             {
  162.                 short itemHit;
  163.  
  164.                 ParamText (fssP->name,nil,nil,nil);
  165.                 ShowWindow (dlgRef);
  166.                 ModalDialog (nil,&itemHit);
  167.                 DisposeDialog (dlgRef);
  168.         
  169.                 if (itemHit == ok)
  170.                     *confirmed = true;
  171.             }
  172.  
  173.             DisposePtr ((Ptr) fssP);
  174.             if (!err) err = MemError ( );
  175.         }
  176.     }
  177.  
  178.     return err;
  179. }
  180.  
  181. static pascal OSErr CountFilesInDir (short vRefNum, long dirID, unsigned short *ioDrNmFls)
  182. {
  183.     OSErr err = noErr;
  184.  
  185.     CInfoPBPtr cipbp = (CInfoPBPtr) NewPtrClear (sizeof (CInfoPBRec));
  186.  
  187.     if (!(err = MemError ( )))
  188.     {
  189.         cipbp->dirInfo.ioVRefNum    = vRefNum;
  190.         cipbp->dirInfo.ioDrDirID    = dirID;
  191.         cipbp->dirInfo.ioFDirIndex    = -1; // ignore ioNamePtr
  192.  
  193.         if (!(err = PBGetCatInfoSync (cipbp)))
  194.             *ioDrNmFls = cipbp->dirInfo.ioDrNmFls;
  195.  
  196.         DisposePtr ((Ptr) cipbp);
  197.         if (!err) err = MemError ( );
  198.     }
  199.  
  200.     return err;
  201. }
  202.  
  203. static pascal OSErr EmptyTrash (short vRefNum)
  204. {
  205.     OSErr    err = noErr;
  206.  
  207.     short    foundVRefNum;
  208.     long    foundDirID;
  209.  
  210.     err = FindFolder (vRefNum,kTrashFolderType,false,&foundVRefNum,&foundDirID);
  211.  
  212.     if (err == fnfErr)    // if the trash ain't there,
  213.         err = noErr;    // consider it empty
  214.     else if (!err)
  215.     {
  216.         unsigned short ioDrNmFls;
  217.  
  218.         if (!(err = CountFilesInDir (foundVRefNum,foundDirID,&ioDrNmFls)))
  219.         {
  220.             if (ioDrNmFls)
  221.             {
  222.                 Boolean confirmed;
  223.         
  224.                 if (!(err = ConfirmEmptyTrash (foundVRefNum,&confirmed)))
  225.                 {
  226.                     if (!confirmed)
  227.                         err = userCanceledErr;
  228.                     else
  229.                     {
  230.                         FSSpecPtr fssP = (FSSpecPtr) NewPtr (sizeof (FSSpec));
  231.                 
  232.                         if (!(err = MemError ( )))
  233.                         {
  234.                             if (!(err = FSMakeFSSpec (foundVRefNum,foundDirID,nil,fssP)))
  235.                                 err = DeleteDirectory (fssP->vRefNum,fssP->parID,fssP->name);
  236.                                 // DeleteDirectory is from MoreFiles
  237.  
  238.                             DisposePtr ((Ptr) fssP);
  239.                             if (!err) err = MemError ( );
  240.                         }
  241.                     }
  242.                 }
  243.             }
  244.  
  245.             if (!err)
  246.                 err = ReleaseFolder (foundVRefNum,kTrashFolderType);
  247.         }
  248.     }
  249.  
  250.     return err;
  251. }
  252.  
  253. pascal OSErr PutAwayOneVolume (short vRefNum, OSType finderLikeProcess)
  254. {
  255.     //
  256.     //    Administrates task of unmounting a volume. If 'finderLikeProcess' is zero,
  257.     //    will attempt to unmount with internal code. (Internal code doesn't yet
  258.     //    work on PowerPC because there's no glue for ReleaseFolder.) If 'finderLikeProcess'
  259.     //    is non-zero, will send AppleEvent which conforms to the Finder Suite's
  260.     //    "put away" spec to that process. For volumes, "put away" means "unmount".
  261.     //
  262.  
  263.     OSErr err = noErr;
  264.  
  265.     if (finderLikeProcess)
  266.         err = PutAwayOneVolumeByAppleEvent (vRefNum,finderLikeProcess);
  267.     else if (!(err = EmptyTrash (vRefNum)))
  268.         err = UnmountAndEject (nil,vRefNum);
  269.         // UnmountAndEject is from MoreFiles
  270.  
  271.     return err;
  272. }
  273.